package com.gopay.scheduler.job;

import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;

import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.common.constants.trans.CertChannelCode;
import com.gopay.common.user.manager.PersonThreeAccountChannelManager;
import com.gopay.common.util.DateUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.common.Result;
import com.gopay.common.constants.cust.CustRealNameCertifyLogConstants;
import com.gopay.common.domain.bank.foundation.IdentityInfoMessage;
import com.gopay.common.domain.cust.CustRealNameCertifyLog;
import com.gopay.common.domain.user.identify.PersCertChannelDTL;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.user.dao.CustRealNameCertifyLogDAO;
import com.gopay.common.user.dao.PersCertChannelDtlDao;
import com.gopay.common.user.dao.UserInfoQueryDAO;
import com.gopay.remote.bank.BisCertificationRemoteService;
import com.gopay.scheduler.GopayBaseJob;
import com.gopay.scheduler.job.vo.CertiryGZTVo;

public class CustRealNameCertifyJob extends GopayBaseJob {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Resource(name = "bisCertificationRemoteService")
	private BisCertificationRemoteService bisCertificationRemoteService;

	@Resource(name = "custRealNameCertifyLogDAO")
	private CustRealNameCertifyLogDAO custRealNameCertifyLogDAO;

	@Resource(name = "userInfoQueryDao")
	private UserInfoQueryDAO userInfoQueryDAO;
	@Resource(name = "persCertChannelDtlDao")
	PersCertChannelDtlDao persCertChannelDtlDao;
	@Resource(name = "commonQueryDAO")
	private CommonQueryDAO commonQueryDAO;

	@Resource(name = "personThreeAccountChannelManager")
	private PersonThreeAccountChannelManager personThreeAccountChannelManager;

	private boolean certificateFlag;
	@Override
	protected void doJobInternal() {
		// 1.获取已实名未认证、已实名已认证，未走国政通， 快捷支付产生的用户，
		List<Object[]> list = queryCust();

		if (list.size() > 0) {
			for (Object[] obj : list) {
				//add by songfengli 20180312 判断是否需要调用第三方服务
				if(!personThreeAccountChannelManager.isTransferCertChannel(obj[2].toString(),obj[0].toString())){
					continue;
				}

				CertiryGZTVo certiryGZTVo = new CertiryGZTVo();
				certiryGZTVo.setCustId(obj[0].toString());
				certiryGZTVo.setCustName(obj[1].toString());
				certiryGZTVo.setCertNo(obj[2].toString());
				// 2.先判断日志中是否有此人认证信息
				CustRealNameCertifyLog certLog = custRealNameCertifyLogDAO.findByCertNoAndName(certiryGZTVo.getCertNo(),
						certiryGZTVo.getCustName());
				if (certLog != null && "0000".equals(certLog.getResultCode())) {//生产优化13期 取实名成功的 lx 2017-12-19 13:42:14
					logger.info("日志查询结果：======" + true);
					if(CertChannelCode.GZT.value.equals(certLog.getChannelCode())){
						addGZTChannel(certiryGZTVo, "01");
					}else{
						if(certificateFlag) {
							exeCertify(certiryGZTVo);
						}
					}
				} else {
				    if(certificateFlag){
					// 调用国政通接口实名认证
					exeCertify(certiryGZTVo);
				    }

				}
			}

		}

	}

	private List<Object[]> queryCust() {
		StringBuilder sb = new StringBuilder();
		sb.append("select distinct(c.cust_id),c.cust_name,c.cert_no from cust_person_info c ")
				.append(" left join user_info u on c.cust_id=u.cust_id ")
				.append(" left join pers_cert_channel_dtl p  on c.cust_id=p.cust_id")
				// modify by sh.jiao 20171201 在in条件中增加‘61’云账户子账户
				//.append(" where c.is_real_name_certify in('1','2') and u.user_source in ('00','01','61')") // 已实名已认证的用户、（pc、wap）快捷支付产生的用户
				//add by songfengli 已实名已认证的用户可以调用国政通来账户升级
				.append(" where c.is_real_name_certify in ('1') ")
				.append(" and p.cust_id not in ")
				.append(" (select cust_id from  pers_cert_channel_dtl p where p.channel_code =:channelCode )");
		//新增时间限制条件 只认证两天内的 未认证记录 生产bug7期 lx 2017-7-24 10:32:21
		sb.append(" and p.created_ts>=to_date(:startDate,'yyyymmdd') ");
		Map<String, Object> map = new HashMap<String, Object>();
		// map.put("userSource", "00");//快捷支付产生的用户
		map.put("channelCode", "01");// 未走国政通的
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, -2);//新增时间限制条件 只认证两天内的 未认证记录 生产bug7期 lx 2017-7-24 10:32:21
		//日期T-2
		String startDate= DateUtils.format(calendar.getTime(), "yyyyMMdd");

		map.put("startDate", startDate);
		return commonQueryDAO.findBySql(sb.toString(), map);
	}

	private void exeCertify(CertiryGZTVo certiryGZTVo) {
		String resultCode = "";
		IdentityInfoMessage base = new IdentityInfoMessage();
		base.setCardHolder(certiryGZTVo.getCustName());
		base.setIdentityCode(certiryGZTVo.getCertNo());
		//标记该国政通是账户等级升级
		base.setIdentity(false);
		logger.info("IdentityInfoMessage==== 姓名：" +  LoggerMaskUtils.maskNameString(base.getCardHolder()) + "身份证号：" +  LoggerMaskUtils.maskString(base.getIdentityCode()));
		try {
			Result certResult = bisCertificationRemoteService.realNameCertify(base);

			logger.error("bisCertificationRemoteService realNameCertify result: "
					+  LoggerMaskUtils.maskString(ToStringBuilder.reflectionToString(certResult)));
			/**
			 * 宣广海修改 修改内容为：certResult.isSuccess()表示操作是否成功，flag表示业务认证是否成功
			 * 修改目的：避免实名认证渠道返回异常报文，比如没有权限调用认证接口报文，如果按照原来的逻辑，
			 * 会把异常情况也认为是没有通过。
			 */
//			if (certResult.isSuccess() && (Boolean) certResult.getModel("flag")) {
//				resultCode = CustRealNameCertifyLogConstants.RESULT_CODE_SUCCESS;
//			} else {
//				resultCode = CustRealNameCertifyLogConstants.RESULT_CODE_FAIL;
//			}
			if (certResult.isSuccess()) {
				if((Boolean) certResult.getModel("flag")){
					resultCode = CustRealNameCertifyLogConstants.RESULT_CODE_SUCCESS;
				}else{
					resultCode = CustRealNameCertifyLogConstants.RESULT_CODE_FAIL;
				}
				
			}else{
				logger.info("========调用国政通接口失败======失败原因："+certResult.getErrorMsg());
			}
		} catch (Exception e) {
			logger.info("========调用国政通接口失败======");
			e.printStackTrace();
		}
		String result = processResult(resultCode, certiryGZTVo);
		if ("success".equals(result)) {
			addGZTChannel(certiryGZTVo, "01");
		} else if ("fail".equals(result)) {
			addGZTChannel(certiryGZTVo, "02");
		}
	}

	public void addGZTChannel(CertiryGZTVo certiryGZTVo, String status) {
		// 增加国政通认证渠道 add by gaocl 20160519("01":国政通)
		PersCertChannelDTL persCertChannel = persCertChannelDtlDao.findByCustIdAndChannel(certiryGZTVo.getCustId(),
				"01");

		if (null == persCertChannel) {
			PersCertChannelDTL persCertChannelDTL = new PersCertChannelDTL();
			persCertChannelDTL.setCertNo(certiryGZTVo.getCertNo());
			persCertChannelDTL.setChannelCode("01");
			persCertChannelDTL.setCustId(certiryGZTVo.getCustId());
			persCertChannelDTL.setCreatedOperId(certiryGZTVo.getCustId());
			persCertChannelDTL.setCreatedTs(new Date());
			persCertChannelDTL.setStatus(status);
			persCertChannelDTL.setRemark("国证通征信实名认证");
			logger.info("新增国政通渠道信息===========" +  LoggerMaskUtils.maskString(persCertChannelDTL.toString()));
			persCertChannelDtlDao.save(persCertChannelDTL);
		}

	}

	private String processResult(String resultCode, CertiryGZTVo certiryGZTVo) {
		// String orderID = paramMap.get("orderID");
		String result = "error";// 默认出错
		try {

			// 保存请求信息
			CustRealNameCertifyLog log = new CustRealNameCertifyLog();
			log.setCustId(certiryGZTVo.getCustId());
			log.setCustName(certiryGZTVo.getCustName());
			log.setCertNo(certiryGZTVo.getCertNo());
			log.setCreatedTs(new Date());
			log.setRemark("CRON");
			// orderID产生100000到999999的随机数
			long Temp;
			Temp = Math.round(Math.random() * 899999 + 100000);
			String orderId = "GOPAY_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + Temp;
			log.setOrderId(orderId);
			log.setResultCode(resultCode);
			log.setChannelCode("01");
			// 认证成功
			if (CustRealNameCertifyLogConstants.RESULT_CODE_SUCCESS.equals(resultCode)) {
				log.setCertResult(CustRealNameCertifyLogConstants.CERT_RESULT_SUCCESS);
				result = "success";
				// 认证失败
			} else if (CustRealNameCertifyLogConstants.RESULT_CODE_FAIL.equals(resultCode)) {
				log.setCertResult(CustRealNameCertifyLogConstants.CERT_RESULT_FAIL);
				log.setFailMessage("姓名和证件号码不匹配");
				result = "fail";
			}

			if (CustRealNameCertifyLogConstants.RESULT_CODE_SUCCESS.equals(resultCode)
					|| CustRealNameCertifyLogConstants.RESULT_CODE_FAIL.equals(resultCode)) {

				custRealNameCertifyLogDAO.save(log);
			} else {
				throw new RuntimeException("身份认证系统繁忙,请稍后再试");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public boolean isCertificateFlag() {
		return certificateFlag;
	}

	public void setCertificateFlag(boolean certificateFlag) {
		this.certificateFlag = certificateFlag;
	}
}